package com.fanketly.funacg2.ui.viewmodels

import android.util.Log
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.paging.Pager
import androidx.paging.PagingConfig
import androidx.paging.PagingData
import androidx.paging.cachedIn
import com.fanketly.funacg2.App
import com.fanketly.funacg2.R
import com.fanketly.funacg2.data.PASSWORD
import com.fanketly.funacg2.data.TAG
import com.fanketly.funacg2.data.model.HistoryModel
import com.fanketly.funacg2.data.model.WorkList
import com.fanketly.funacg2.data.network.Result
import com.fanketly.funacg2.data.network.flowResult
import com.fanketly.funacg2.data.paging.WorkPagingSource
import com.fanketly.funacg2.data.repo.AudioRepo
import com.fanketly.funacg2.data.repo.HistoryRepo
import com.fanketly.funacg2.data.tFilterMenuList
import com.fanketly.funacg2.ui.viewmodels.state.GlobalState
import com.fanketly.funacg2.ui.viewmodels.state.HomeState
import com.fanketly.funacg2.utils.StringUtils
import com.fanketly.funacg2.utils.ToastUtils
import com.fanketly.funacg2.utils.getAppString
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class HomeViewModel @Inject constructor(
    private val audioRepo: AudioRepo,
    private val historyRepo: HistoryRepo,
    private val globalStates: GlobalStates,
) : ViewModel() {
    ///////////////////////////////////////////////////////////////////////////
    /*参数区*/
    ///////////////////////////////////////////////////////////////////////////
    private val _homeUiState: MutableState<HomeState> = mutableStateOf(HomeState.Loading)
    val homeUiState
        get() = _homeUiState.value
    val globalState
        get() = globalStates.globalUiState
    var selectedFilterData = mutableStateOf(tFilterMenuList[0])

    private val _recommendList = mutableStateOf(emptyList<WorkList.Work>())
    val recommendList
        get() = _recommendList.value

    var isFirstToShowThisTagScreen = true


    val pager: Flow<PagingData<WorkList.Work>> = Pager(
        PagingConfig(
            pageSize = 20, initialLoadSize = 20, enablePlaceholders = true, maxSize = 200
        )
    ) {
        WorkPagingSource(selectedFilterData.value, audioRepo)
    }.flow.cachedIn(viewModelScope)


    ///////////////////////////////////////////////////////////////////////////
    /*方法区*/
    ///////////////////////////////////////////////////////////////////////////
    fun openDrawer() = globalStates.openDrawer()
//    fun selectOrder(filterMenuItemData: FilterMenuItemData) {
//        if (source == null) {
//
//            source = WorkPagingSource(filterMenuItemData, audioRepo)
//        } else if (source!!.filterMenuItemData.name != filterMenuItemData.name) {
//            source = WorkPagingSource(filterMenuItemData, audioRepo)
//        }
//    }

    init {
        Log.i(TAG, "HomeViewModel_init: ")
    }

    fun getRecommend() {
        viewModelScope.launch {
            _recommendList.value = audioRepo.getRecommend().works
        }
    }

    /**
     * token是否过期，过期自动登录
     * */
    fun isExpires() {
        if (App.sToken.isNotEmpty()) viewModelScope.launch {
            kotlin.runCatching {
                audioRepo.isExpires()
            }.onFailure {//过期了
                audioRepo.getAuth(App.sUsername, App.sMMKV.decodeString(PASSWORD, "")!!).collect {
                    when (it) {
                        is Result.Success -> {
                            if (it.data.success) {
                                App.sToken = it.data.data.token
                                Log.i(TAG, "isExpires_getAuth:${App.sToken} ")
                            }
                            ToastUtils.shortToast(it.data.message)
                        }

                        is Result.Loading -> {
                        }

                        is Result.Error -> {
                            App.logout()
                            ToastUtils.shortToast("自动登录失败，${it.exception?.localizedMessage}")
                        }
                    }
                }
            }
        }
    }

    fun register(username: String, password: String, onSuccess: () -> Unit) {
        viewModelScope.launch {
            audioRepo.register(username, password).collect {
                when (it) {
                    is Result.Error -> ToastUtils.shortToast("注册失败：" + it.exception?.localizedMessage)
                    Result.Loading -> {}
                    is Result.Success -> {
                        ToastUtils.shortToast("注册成功")
                        onSuccess()
                    }
                }
            }
        }
    }

    fun login(username: String, password: String, onSuccess: () -> Unit) {
        viewModelScope.launch {
            audioRepo.getAuth(username, password).collect {
                when (it) {
                    is Result.Success -> {
                        if (it.data.success) {
                            val token = it.data.data.token
                            Log.i(TAG, "getAuth:${token} ")
                            App.setUserData(username, password, token)
                            globalStates.setStateClose()
                            onSuccess()
                        }
                        ToastUtils.shortToast(it.data.message)
                    }

                    is Result.Loading -> {
                        globalStates.showLoading()
                    }

                    is Result.Error -> {
                        globalStates.showToast(StringUtils.getFailString(it.exception?.message))
                    }
                }
            }
        }
    }


    /**
     * 获取音声
     * */
    fun getAudio(work: WorkList.Work) {
        viewModelScope.launch {
            flowResult { emit(audioRepo.getAudio(work.id)) }.map {
                when (it) {
                    is Result.Success -> {
                        if (App.isLogin()) launch {
                            historyRepo.insert(
                                HistoryModel(
                                    work.id,
                                    work.title,
                                    work.img240,
                                    null,
                                    App.sUsername
                                )
                            )
                        }
                        GlobalState.ToDetail(it.data, work)
                    }

                    is Result.Error -> {
                        val message =
                            it.exception?.localizedMessage ?: getAppString(R.string.load_failed)
                        if (message.contains("Chain validation failed") || message.contains("401")) GlobalState.NotAuthorization
                        else GlobalState.ShowToast(message)
                    }

                    Result.Loading -> GlobalState.Loading
                }
            }.collect {
                globalStates.collectState(it)
            }
        }
    }

    fun setStateClose() = globalStates.setStateClose()

}
